"""
分析任务相关模型
"""
from models.petition_record import RegionalAnalysisResult
from datetime import datetime, timezone
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey, JSON, Float, extract
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from enum import Enum
from typing import Optional, Dict, Any

from .base import Base, TimestampMixin, ActiveMixin


class TaskStatus(str, Enum):
    """任务状态枚举"""
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"
    TIMEOUT = "timeout"


class TaskType(str, Enum):
    """分析任务类型 枚举"""
    RegionalAnalysis = "RegionalAnalysis"  # 区域分析
    ComplaintTypeAnalysis = "ComplaintTypeAnalysis" # 信访类型分析
    SentimentAnalysis = "SentimentAnalysis" # 情感分析
    ComplianceAnalysis = "ComplianceAnalysis"  # 规范性分析
    DuplicateAnalysis = "DuplicateAnalysis" # 重复信访分析

class ExecutionType(str, Enum):
    """任务类型枚举"""
    BATCH_ANALYSIS = "batch_analysis"
    SINGLE_ANALYSIS = "single_analysis"


class AnalysisTask(Base, TimestampMixin, ActiveMixin):
    """分析任务模型"""
    
    __tablename__ = "analysis_task"
    
    # 基本信息
    name = Column(String(200), nullable=False, comment="任务名称")
    task_type = Column(String(200), default=TaskType.RegionalAnalysis.value, nullable=False, comment="任务类型（支持多选，逗号分隔）")
    execution_type = Column(String(50), default=ExecutionType.SINGLE_ANALYSIS.value, nullable=False, comment="执行类型")
    status = Column(String(20), default=TaskStatus.PENDING.value, comment="任务状态")
    
    # 分析时段设置
    analysis_start_date = Column(DateTime, comment="分析开始日期")
    analysis_end_date = Column(DateTime, comment="分析结束日期")
    
    # 任务配置
    config = Column(JSON, comment="任务配置")
    services = Column(JSON, comment="服务配置")
    
    # 执行信息
    start_time = Column(DateTime, comment="开始时间")
    end_time = Column(DateTime, comment="结束时间")
    duration = Column(Float, comment="执行时长(秒)")
    progress = Column(Float, default=0.0, comment="进度(0-100)")
    
    # 结果统计
    total_count = Column(Integer, default=0, comment="总数量")
    success_count = Column(Integer, default=0, comment="成功数量")
    failed_count = Column(Integer, default=0, comment="失败数量")
    
    # 重试配置
    retry_count = Column(Integer, default=0, comment="重试次数")
    max_retries = Column(Integer, default=3, comment="最大重试次数")
    
    # 数据源关联
    data_source_id = Column(Integer, ForeignKey('data_source.id'), comment="数据源ID")
    
    # 创建者
    creator_id = Column(Integer, ForeignKey('user.id'), comment="创建者ID")
    
    # 错误信息
    error_message = Column(Text, comment="错误信息")
    error_details = Column(JSON, comment="错误详情")
    
    # 关系
    data_source = relationship("DataSource", back_populates="analysis_tasks")
    # creator = relationship("User", back_populates="created_tasks")
    # results = relationship("AnalysisResult", back_populates="task")
    services_log = relationship("TaskService", back_populates="task")
    
    def start_execution(self):
        """开始执行任务"""
        self.status = TaskStatus.RUNNING
        self.start_time = datetime.now()
        self.progress = 0.0
    
    def update_progress(self, progress: float, processed_count: int = None):
        """更新进度"""
        self.progress = max(0.0, min(100.0, progress))
        if processed_count is not None:
            self.success_count = processed_count
    
    def complete_execution(self, start_time, success_count: int = None, failed_count: int = None):
        """完成任务"""
        self.start_time = start_time
        self.status = TaskStatus.COMPLETED
        self.end_time = datetime.now()
        if self.start_time:
            self.start_time = self.start_time.replace()
            self.duration = (self.end_time - self.start_time).total_seconds()
        
        if success_count is not None:
            self.success_count = success_count
        if failed_count is not None:
            self.failed_count = failed_count
        if self.total_count == 0:
            self.total_count = self.success_count + self.failed_count
        
        self.progress = 100.0
    
    def fail_execution(self, error_message: str = None, error_details: Dict = None):
        """任务失败"""
        self.status = TaskStatus.FAILED
        self.end_time = datetime.now()
        if self.start_time:
            self.start_time = self.start_time.replace()
            self.duration = (self.end_time - self.start_time).total_seconds()
        
        self.error_message = error_message
        self.error_details = error_details
    
    def cancel_execution(self):
        """取消任务"""
        self.status = TaskStatus.CANCELLED
        self.end_time = datetime.now()
        if self.start_time:
            self.start_time = self.start_time.replace()
            self.duration = (self.end_time - self.start_time).total_seconds()
    
    def can_retry(self) -> bool:
        """检查是否可以重试"""
        return (
            self.status in [TaskStatus.FAILED, TaskStatus.TIMEOUT] and
            self.retry_count < self.max_retries
        )
    
    def retry(self):
        """重试任务"""
        if self.can_retry():
            self.retry_count += 1
            self.status = TaskStatus.PENDING
            self.start_time = None
            self.end_time = None
            self.duration = None
            self.progress = 0.0
            self.error_message = None
            self.error_details = None
    
    def get_duration_display(self) -> str:
        """获取执行时长显示"""
        if self.duration is None:
            return "未开始"
        elif self.duration < 60:
            return f"{self.duration:.1f}秒"
        elif self.duration < 3600:
            return f"{self.duration/60:.1f}分钟"
        else:
            return f"{self.duration/3600:.1f}小时"
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        result['duration_display'] = self.get_duration_display()
        result['can_retry'] = self.can_retry()
        return result


class TaskService(Base, TimestampMixin):
    """任务服务记录模型"""
    
    __tablename__ = "task_service"
    
    # 关联
    task_id = Column(Integer, ForeignKey('analysis_task.id'), nullable=False, comment="任务ID")
    
    # 服务信息
    service_name = Column(String(100), nullable=False, comment="服务名称")
    service_type = Column(String(50), comment="服务类型")
    service_version = Column(String(20), comment="服务版本")
    
    # 执行信息
    start_time = Column(DateTime, comment="开始时间")
    end_time = Column(DateTime, comment="结束时间")
    duration = Column(Float, comment="执行时长(秒)")
    status = Column(String(20), comment="状态")
    
    # 结果统计
    input_count = Column(Integer, comment="输入数量")
    output_count = Column(Integer, comment="输出数量")
    success_count = Column(Integer, comment="成功数量")
    failed_count = Column(Integer, comment="失败数量")
    
    # 性能指标
    avg_response_time = Column(Float, comment="平均响应时间")
    max_response_time = Column(Float, comment="最大响应时间")
    min_response_time = Column(Float, comment="最小响应时间")
    
    # 错误信息
    error_message = Column(Text, comment="错误信息")
    error_details = Column(JSON, comment="错误详情")
    
    # 关系
    task = relationship("AnalysisTask", back_populates="services_log")
    
    def start_service(self):
        """开始服务"""
        self.start_time = datetime.now()
        self.status = "running"
    
    def complete_service(self, start_time, input_count: int = 0, output_count: int = 0,
                       success_count: int = 0, failed_count: int = 0):
        """完成服务"""
        self.start_time = start_time
        self.end_time = datetime.now()
        self.status = "completed"
        
        if self.start_time:
            self.start_time = self.start_time.replace()
            self.duration = (self.end_time - self.start_time).total_seconds()
        
        self.input_count = input_count
        self.output_count = output_count
        self.success_count = success_count
        self.failed_count = failed_count
    
    def fail_service(self, error_message: str = None, error_details: Dict = None):
        """服务失败"""
        self.end_time = datetime.now()
        self.status = "failed"
        self.error_message = error_message
        self.error_details = error_details
        
        if self.start_time:
            self.start_time = self.start_time.replace()
            self.duration = (self.end_time - self.start_time).total_seconds()
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result


class TaskTemplate(Base, TimestampMixin, ActiveMixin):
    """任务模板模型"""
    
    __tablename__ = "task_template"
    
    # 基本信息
    name = Column(String(200), nullable=False, comment="模板名称")
    description = Column(Text, comment="模板描述")
    task_type = Column(String(50), nullable=False, comment="任务类型")
    category = Column(String(50), comment="模板分类")
    
    # 模板配置
    config = Column(JSON, comment="任务配置模板")
    services = Column(JSON, comment="服务配置模板")
    field_mapping = Column(JSON, comment="字段映射模板")
    
    # 使用统计
    usage_count = Column(Integer, default=0, comment="使用次数")
    last_used = Column(DateTime, comment="最后使用时间")
    
    # 创建者
    creator_id = Column(Integer, ForeignKey('user.id'), comment="创建者ID")
    
    # 是否系统模板
    is_system = Column(Boolean, default=False, comment="是否系统模板")
    
    # 关系
    creator = relationship("User")
    
    def increment_usage(self):
        """增加使用次数"""
        self.usage_count += 1
        self.last_used = func.now()
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result